# yun-cha-coffee PyCharm
# 2025/8/30 16:56
# YunCha-Coffee PyCharm
# user 86155
# 2025/8/30 1:15
from datetime import datetime
from http import HTTPStatus

from fastapi import APIRouter, Depends, HTTPException, Query, status, Body
from sqlalchemy.exc import OperationalError
from typing import Union, List, Optional, Dict, Any
from app.models import *
from pydantic import BaseModel, validator, Field, ConfigDict
from tortoise.contrib.pydantic import pydantic_model_creator
from app.dependencies import get_current_user


#
# FavoritePydantic = pydantic_model_creator(Favorite, name="Favorite")
# FavoriteInPydantic = pydantic_model_creator(Favorite, name="FavoriteIn", exclude_readonly=True)



favorite_api = APIRouter(prefix="/favorite")

class FavoritePydantic(BaseModel):
    id: int
    user_id: int
    product_id: int
    product_type: ProductTypeEnum
    created_at: datetime

    model_config = ConfigDict(
        from_attributes=True,
        populate_by_name=True,
    )






'''
查询用户个人收藏夹列表
'''


@favorite_api.get("/", summary="查询所有收藏")
async def get_all_favorites():
    """查询所有收藏记录（可能需要管理员权限）"""
    favorites = await Favorite.all()

    return {
        "code":200,
        "message":"查询成功",
        "data":favorites
    }


@favorite_api.get("/my", summary="获取当前用户的收藏")
async def get_my_favorites(
        current_user: User = Depends(get_current_user),
):
    """获取当前用户的收藏列表"""
    # 获取当前用户的收藏
    favorites = await Favorite.filter(user_id=current_user.id).all()

    favorite_list = []


    for favorite in favorites:
        # 根据product_type和product_id获取商品信息
        if favorite.product_type == "coffee":
            product = await CoffeeProduct.filter(id=favorite.product_id).first()
        elif favorite.product_type == "merchandise":
            # 如果是 merchandise，你可能需要查询另一个表
            # 这里假设 merchandise 也在 Product 表中，或者你需要修改
            product = await MerchandiseProduct.filter(id=favorite.product_id).first()
        else:
            product = None

        if product:
            favorite_data = {
                "id": favorite.id,
                "product_id": favorite.product_id,
                "product_type": favorite.product_type,
                "user_id": favorite.user_id,
                "created_at": favorite.created_at,
                "name": product.name,
                "price": float(product.price),
                "image_urls": product.image_urls[0] if product.image_urls else None
            }
            favorite_list.append(favorite_data)
        else:
            # 如果商品不存在，仍然返回收藏信息
            favorite_data = {
                "id": favorite.id,
                "product_id": favorite.product_id,
                "product_type": favorite.product_type,
                "user_id": favorite.user_id,
                "created_at": favorite.created_at,
                "name": "商品已下架",
                "price": 0,
                "image_urls": None
            }
            favorite_list.append(favorite_data)

    return {
        "code": 200,
        "message": "成功",
        "data": favorite_list
    }


@favorite_api.get("/my/page", summary="根据分页和商品类型获取用户的收藏")
async def get_favorites_by_page(
        current_user: User = Depends(get_current_user),
        page: int = Query(1, ge=1, description="页码，从1开始"),
        limit: int = Query(10, ge=1, le=100, description="每页数量，1-100之间"),
        product_type: Optional[str] = Query(None, description="商品类型，如 coffee、merchandise 等")
):
    try:
        # 基础查询（不执行，仅构建查询条件）
        query = Favorite.filter(user_id=current_user.id).all()

        # 新增：根据product_type筛选收藏
        if product_type:
            # 验证传入的类型是否合法
            valid_types = ["coffee", "merchandise"]
            if product_type not in valid_types:
                return {
                    "code": 400,
                    "message": f"无效的商品类型，合法类型：{valid_types}",
                    "data": None
                }
            # 应用类型筛选条件
            query = query.filter(product_type=product_type)

        # 获取总数（用于分页，已包含类型筛选）
        total = await query.count()

        # 计算偏移量
        offset = (page - 1) * limit

        # 执行查询（带分页和类型筛选）
        favorites = await query.offset(offset).limit(limit).all()

        # 计算总页数
        total_pages = (total + limit - 1) // limit if total > 0 else 1

        favorite_list = []

        for favorite in favorites:
            # 根据product_type和product_id获取商品信息
            if favorite.product_type == "coffee":
                product = await CoffeeProduct.filter(id=favorite.product_id).first()
            elif favorite.product_type == "merchandise":
                product = await MerchandiseProduct.filter(id=favorite.product_id).first()
            else:
                product = None

            if product:
                favorite_data = {
                    "id": favorite.id,
                    "product_id": favorite.product_id,
                    "product_type": favorite.product_type,
                    "user_id": favorite.user_id,
                    "created_at": favorite.created_at,
                    "name": product.name,
                    "price": float(product.price),
                    "original_price":float(product.original_price),
                    "image_urls": product.image_urls[0] if product.image_urls else None
                }
            else:
                favorite_data = {
                    "id": favorite.id,
                    "product_id": favorite.product_id,
                    "product_type": favorite.product_type,
                    "user_id": favorite.user_id,
                    "created_at": favorite.created_at,
                    "name": "商品已下架",
                    "price": 0,
                    "original_price": 0,
                    "image_urls": None
                }
            favorite_list.append(favorite_data)

        return {
            "code": 200,
            "message": "成功",
            "data": {
                "favorite_list": favorite_list,
                "pagination": {
                    "page": page,
                    "limit": limit,
                    "total": total,  # 已筛选后的总数
                    "total_pages": total_pages,
                    "has_next": page < total_pages,
                    "has_prev": page > 1,
                    "current_type": product_type or "all"  # 返回当前筛选类型
                }
            }
        }

    except Exception as e:
        print(f"获取收藏列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail="服务器错误，获取收藏列表失败")



# 定义请求体的 Pydantic 模型（明确需要的字段）
class FavoriteCreate(BaseModel):
    product_id: int
    product_type: str


@favorite_api.post("/add", summary="用户添加收藏", response_model=dict)
async def add_favorite(
        favorite_data: FavoriteCreate = Body(...),
        current_user: User = Depends(get_current_user)
):
    try:
        # 检查是否已存在相同记录
        existing = await Favorite.filter(
            user_id=current_user.id,
            product_id=favorite_data.product_id,
            product_type=favorite_data.product_type
        ).first()

        if existing:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="该商品已被收藏"
            )

        # 创建新收藏
        favorite = await Favorite.create(
            user_id=current_user.id,
            product_id=favorite_data.product_id,
            product_type=favorite_data.product_type
        )

        # 确保 favorite 有 id 属性
        if not hasattr(favorite, 'id'):
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="收藏创建失败，缺少 ID"
            )

        # 将 Favorite 模型实例转换为纯字典
        favorite_dict = {
            "id": favorite.id,
            "user_id": favorite.user_id,  # 或者 favorite.user.id，取决于模型定义
            "product_id": favorite.product_id,
            "product_type": favorite.product_type,
        }

        return {
            "code": 200,
            "message": "收藏成功",
            "data": favorite_dict
        }

    except OperationalError as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"数据库操作失败: {str(e)}"
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"服务器内部错误: {str(e)}"
        )





# 收藏详情响应模型
class FavoriteDetailResponse(BaseModel):
    favorite_info: FavoritePydantic
    product_info: dict

    model_config = ConfigDict(from_attributes=True)

@favorite_api.get("/{id}",summary="查询用户的某一个收藏的详细信息")
async def getOneFavoritedetail(favorite_id: int, user_id: int):
    # 获取收藏记录
    favorite = await Favorite.filter(id=favorite_id, user_id=user_id).first()

    if not favorite:
        raise HTTPException(status_code=404, detail="收藏记录不存在")

    # 确保 product_type 是有效的枚举值
    if not isinstance(favorite.product_type, ProductTypeEnum):
        try:
            favorite.product_type = ProductTypeEnum(favorite.product_type or "coffee")
        except ValueError:
            favorite.product_type = ProductTypeEnum.COFFEE

    # 获取商品详细信息（这里需要根据您的实际商品模型进行实现）
    product_info = await get_product_info(favorite.product_id, favorite.product_type)

    return {
        "code": 200,
        "message": "查询成功",
        "data": {
            "favorite_info": FavoritePydantic.model_validate(favorite),
            "product_info": product_info
        }
    }
async def get_product_info(product_id: int, product_type: ProductTypeEnum):
    if product_type == ProductTypeEnum.COFFEE:
        product = await CoffeeProduct.filter(id=product_id).first()
        if product:
            return {
                "id": product.id,
                "name": product.name,
                "description": product.description,
                "price": product.price,
                "image_urls": product.image_urls,
                "stock": product.stock,
            }
    else:
        product = await MerchandiseProduct.filter(id=product_id).first()
        if product:
            return {
                "id": product.id,
                "name": product.name,
                "description": product.description,
                "price": product.price,
                "image_urls": product.image_urls,
                "stock": product.stock,
            }


class FavoriteInPydantic(BaseModel):
    user_id: int
    product_id: int
    product_type: ProductTypeEnum

    model_config = ConfigDict(from_attributes=True)


@favorite_api.post("/")
async def addFavorite(favorite_data:FavoriteInPydantic):
    """添加商品到收藏夹"""
    # 检查是否已收藏
    existing = await Favorite.filter(
        user_id=favorite_data.user_id,
        product_id=favorite_data.product_id,
        product_type=favorite_data.product_type
    ).first()

    if existing:
        raise HTTPException(status_code=400, detail="已收藏该商品")

    favorite = await Favorite.create(**favorite_data.dict())
    return {
        "code":200,
        "message": "添加收藏成功",
        "data": favorite
    }


@favorite_api.delete("/delete", summary="删除所有收藏")
async def delete_all_favorites(
        current_user: User = Depends(get_current_user)
):
    """
    删除当前用户的所有收藏
    """
    count = await Favorite.filter(user_id=current_user.id).delete()

    if count > 0:
        return {
            "code": 200,
            "message": f"成功删除 {count} 个收藏",
            "data": None
        }
    else:
        return {
            "code": 200,
            "message": "没有找到收藏记录",
            "data": None
        }

@favorite_api.delete("/",summary="删除该用户收藏")

async def delete_favorite(
    product_id: int,
    product_type: str,
    current_user: User = Depends(get_current_user),

):
    favorite = await Favorite.filter(
        user_id=current_user.id,
        product_id=product_id,
        product_type=product_type
    ).first()
    if favorite:
        await favorite.delete()
        return {
            "code": 200,
            "message": "删除成功"
        }
    else:
        raise HTTPException(status_code=404, detail="收藏记录不存在")




class FavoriteUpdate(BaseModel):
    product_type: Optional[ProductTypeEnum] = None


@favorite_api.put("/{favorite_id}",summary="修改收藏")
async def updateFavorite(favorite_id: int, update_data: FavoriteUpdate, user_id: int):
    """修改收藏信息"""
    # 获取收藏记录
    favorite = await Favorite.filter(id=favorite_id, user_id=user_id).first()

    if not favorite:
        raise HTTPException(status_code=404, detail="收藏记录不存在")

    # 检查是否已存在相同的收藏（用户+产品+类型）
    if update_data.product_type:
        existing = await Favorite.filter(
            user_id=user_id,
            product_id=favorite.product_id,
            product_type=update_data.product_type
        ).exclude(id=favorite_id).first()

        if existing:
            raise HTTPException(status_code=400, detail="已存在相同类型的收藏")

    # 更新收藏信息
    update_dict = update_data.dict(exclude_unset=True)
    await favorite.update_from_dict(update_dict).save()

    # 重新加载更新后的数据
    await favorite.refresh_from_db()

    return {
        "code":200,
        "message":"修改成功"
    }
